package com.bys.generator.core;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import com.bys.generator.base.BaseModel;
import com.bys.generator.constant.CodeConstent;
import com.bys.generator.util.ScannerUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicReference;
public class MysqlGenerator {
    private String packagePath;
    private String driver;
    private String url;
    private String username;
    private String password;

    public  void createCode(){
        String project_dir = null;
        // module 名字
        String moduleName = null;
        String tableName = null;
        String tablePrefix = null;
        Properties properties = new Properties();

        try {
            InputStream ins = Resources.getResourceAsStream("generator-db.properties");
            properties.load(ins);
        } catch (IOException e) {
            throw new RuntimeException("generator-db.properties 配置文件 未找到, 请放入到 类的根路径下");
        }
        packagePath = properties.getProperty(CodeConstent.groupId);
        driver = properties.getProperty(CodeConstent.driver);
        url = properties.getProperty(CodeConstent.url);
        username = properties.getProperty(CodeConstent.username);
        password = properties.getProperty(CodeConstent.password);
        moduleName = properties.getProperty(CodeConstent.MODULE_NAME);
        tableName = properties.getProperty(CodeConstent.TABLE_NAME);
        tablePrefix = properties.getProperty(CodeConstent.IGNORE_TABLE_PREFIX);
        // 项目的根路径
        String classPath = Objects.requireNonNull(this.getClass().getResource("/")).getPath();
        try {
            classPath = URLDecoder.decode(classPath, String.valueOf(StandardCharsets.UTF_8));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        if(Objects.isNull(classPath)){
            project_dir = System.getProperty(CodeConstent.PROJECT_DIR);
        }else{
            int target = classPath.indexOf(CodeConstent.TARGET_DIR);
            project_dir = classPath.substring(0,target);
        }
        //  公司域名 包
        String groupPath = packagePath.replace(".", File.separator);
        StringJoiner stringJoiner = new StringJoiner(File.separator);
        StringJoiner projectAllPath = stringJoiner.add(project_dir).add(groupPath).add(moduleName);
        FastAutoGenerator generator = FastAutoGenerator.create(defaultDataSource());
        // 全局配置
        String finalProject_dir = project_dir;
        generator.globalConfig(builder -> {
            builder.outputDir(finalProject_dir + "\\src\\main\\java").author("bys")
                    // 打开 swaager
                    .enableSwagger()
                    // 禁止打开输出目录
                    .disableOpenDir()
                    // 文件覆盖
                    .fileOverride()
                    .build();
        });
        // 自定义 包配置
        String finalModuleName = moduleName;
        generator.packageConfig(builder -> {
            builder.parent(packagePath)
                    .moduleName(finalModuleName)
                    .entity("model")
                    .mapper("mapper")
                    .xml("mapper")
                    .service("service")
                    .serviceImpl("service.impl")
                    .controller("controller")
                    .build();
        });
        // 自定义策略配置
        String finalTableName = tableName;
        String finalTablePrefix = tablePrefix;
        generator.strategyConfig(builder -> {
            String[] tables = finalTableName.split(",");
            builder.addInclude(tables)
                    .addTablePrefix(finalTablePrefix)
                    // 实体类构建
                    .entityBuilder()
                    .enableLombok()
                    .enableTableFieldAnnotation()
                    //数据库表映射到实体的命名策略 underline_to_camel 转驼峰
                    .naming(NamingStrategy.underline_to_camel)
                    //数据库表字段映射到实体的命名策略
                    .columnNaming(NamingStrategy.underline_to_camel)
                    .idType(IdType.AUTO)
                    .formatFileName("%sModel")
                    // mapper 构建
                    .mapperBuilder()
                    .enableBaseResultMap()
                    .enableBaseColumnList()
                    .formatMapperFileName("%sMapper")
                    .formatXmlFileName("%sMapper")
                    .serviceBuilder()
                    .formatServiceFileName("I%sService")
                    .formatServiceImplFileName("%sServiceImpl")
                    .controllerBuilder()
                    //开启生成@RestController控制器
                    .enableRestStyle()
                    //开启驼峰转连字符
                    .enableHyphenStyle()
                    .formatFileName("%sController")
                    .build();
        });
        // 模板设置
        generator.templateConfig(builder -> {
            builder.entity("/templates/entity.java")
                    .service("/templates/service.java")
                    .serviceImpl("/templates/serviceImpl.java")
                    .mapper("/templates/mapper.java")
                    .mapperXml("/templates/mapper.xml")
                    .controller("/templates/controller.java")
                    .build();
        });
        generator.templateEngine(new FreemarkerTemplateEngine()).execute();
    }

    private DataSourceConfig.Builder defaultDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return new DataSourceConfig.Builder(dataSource).keyWordsHandler(new MySqlKeyWordsHandler()).typeConvert(new MySqlTypeConvert());
    }

}
